#!/usr/bin/python
#
# Copyright 2011 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Sample to use google-api-python client for the Calendar API with
gdata-python-client for the EmailSettings API to automatically update 
vacation-responder settings.

Usage:
  $ python vacation-responder.py --username [username@domain] --domain [domain]
"""

__author__ = 'Shraddha Gupta <shraddhag@google.com>'

import datetime
import os
import sys

from apiclient.discovery import build
import gdata.apps.emailsettings.client
import gflags
import httplib2
from oauth2client.client import flow_from_clientsecrets
from oauth2client.file import Storage
from oauth2client.tools import run


# CLIENT_SECRETS, name of a file containing the OAuth 2.0 information for this
# application, including client_id and client_secret, which are found
# on the API Access tab on the Google APIs
# Console <http://code.google.com/apis/console>
CLIENT_SECRETS = 'client_secrets.json'

# Helpful message to display in the browser if the CLIENT_SECRETS file
# is missing.
MISSING_CLIENT_SECRETS_MESSAGE = """
WARNING: Please configure OAuth 2.0

To make this sample run you will need to populate the client_secrets.json file
found at:

   %s

with information from the APIs Console <https://code.google.com/apis/console>.

""" % os.path.join(os.path.dirname(__file__), CLIENT_SECRETS)

# Request a token for the scope of two APIs: Calendar and Email Settings APIs
SCOPE = ('https://www.googleapis.com/auth/calendar '
     'https://apps-apis.google.com/a/feeds/emailsettings/2.0/')

# Set up a Flow object to be used if we need to authenticate.
FLOW = flow_from_clientsecrets(CLIENT_SECRETS,
    scope=SCOPE,
    message=MISSING_CLIENT_SECRETS_MESSAGE)

FLAGS = gflags.FLAGS
gflags.DEFINE_string('username', None,
                     ('User email for which vacation responder is updated'))
gflags.DEFINE_string('domain', None,
                     ('Domain name of the admin'))


def get_auth2token(client_id, client_secret, access_token, refresh_token):
  """Get the OAuth 2.0 token for using with the EmailSettings API.
  Args:
    client_id: client_id of the installed application
    client_secret: client_secret of the installed application
    access_token: access token obtained from OAuth 2.0 server flow
    refresh_token: refresh token obtained with access token

  Returns:
    token: OAuth 2.0 token to be used with Emailsettings API.
  """
  token = gdata.gauth.OAuth2Token(client_id=client_id,
                                  client_secret=client_secret,
                                  scope=SCOPE,
                                  access_token=access_token,
                                  refresh_token=refresh_token,
                                  user_agent='vacation-responder-sample/1.0')
  return token

def set_vacation_responder(http, email_client, username):
  """Update the vacation responder using the calendar vacation event.
  Args:
    http: httplib2.Http authorized object
    email_client: gdata.apps.emailsettings.client.EmailSettingsClient
                  authorized client
    username: string username@domain
  """
  cur_datetime = datetime.datetime.now()
  # Convert the date to the RFC 3339 timestamp format for Calendar API.
  cur_date = cur_datetime.strftime('%Y-%m-%dT%H:%M:%SZ')

  service = build('calendar', 'v3', http=http)
  # Retrieve the event list querying 'vacation' events starting from today
  events = service.events().list(calendarId=username,
      q='vacation', timeMin=cur_date, singleEvents=True,
      orderBy='startTime').execute()

  # If list is not empty set the vacation responder for first vacation event. 
  if 'items' in events:
    for event in events['items']:
      startDate = event['start']
      endDate = event['end']
      # If event is set for the day not just for a time slot.
      if 'date' in startDate:
        email_client.UpdateVacation(username=username, enable=True,
            subject='Out of office', message='If urgent call me.',
            domain_only=True, start_date=startDate['date'],
            end_date=endDate['date'])
        print '\n Vacation responder set for the days between %s to %s'  % (
            startDate['date'], endDate['date'])
        break


def main(argv):
  try:
    argv = FLAGS(argv)
  except gflags.FlagsError, e:
    print '%s\\nUsage: %s ARGS\\n%s' % (e, argv[0], FLAGS)
    sys.exit(1)

  username = FLAGS.username
  domain = FLAGS.domain
  if None in (username, domain):
    print 'Please enter username@domain and domain as parameters.'
    print 'Use --help for help on parameters'
    sys.exit(1)

  # http should have been authorized by the credentials.
  # the OAuth scope is 'https://www.googleapis.com/auth/calendar'
  storage = Storage('vacation.dat')
  credentials = storage.get()
  if credentials is None or credentials.invalid:
    print 'Credentials are invalid or do not exist.'
    credentials = run(FLOW, storage)

  # Create an httplib2.Http object to handle our HTTP requests and authorize it
  # with our good Credentials.
  http = httplib2.Http()
  http = credentials.authorize(http)

  # Create an OAuth 2.0 token suitable for use with the Gdata client library
  auth2token = get_auth2token(credentials.client_id, credentials.client_secret,
                              credentials.access_token,
                              credentials.refresh_token)
  email_client = auth2token.authorize(
      gdata.apps.emailsettings.client.EmailSettingsClient(domain=domain))
  set_vacation_responder(http, email_client, username)


if __name__ == '__main__':
  main(sys.argv)
